/*
 * Copyright 2011 Clean GWT
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cleangwt.user.cellview.client;

import com.cleangwt.bootstrap.client.ui.Navigator;
import com.cleangwt.bootstrap.client.ui.Navigators;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.LIElement;
import com.google.gwt.user.cellview.client.AbstractPager;
import com.google.gwt.user.client.Event;

/**
 * A pager provides indexes for quick navigation.
 * 
 * @author Jess
 * @version 1.0
 * @since 1.0
 */
public class PaginationPager extends AbstractPager {

  private static final String FIRST = "&laquo;";
  private static final String LAST = "&raquo;";
  private static final String NEXT = "&rsaquo;";
  private static final String PREV = "&lsaquo;";

  private Navigator navigator = new Navigator();
  private int visiblePaginations;

  /**
   * Creates a indexed pager.
   */
  public PaginationPager() {
    this(10);
  }

  @Override
  public void onBrowserEvent(Event event) {
    super.onBrowserEvent(event);
    int type = event.getTypeInt();
    if (type == Event.ONCLICK) {
      if (Element.is(event.getEventTarget())) {
        Element e = Element.as(event.getEventTarget());
        // set active for list item
        if (AnchorElement.TAG.equalsIgnoreCase(e.getTagName())
            && LIElement.TAG.equalsIgnoreCase(e.getParentElement().getTagName())) {
          int index = navigator.getItemIndex(e.getParentElement());
          if (index < 0) {
            return;
          }
          if (index == 0) {
            if (getPage() > 0) {
              firstPage();
            } else {
              // reset active
              navigator.setActive(2);
            }
          } else if (index == 1) {
            if (getPage() > 0) {
              // previousPage();
              setPage(getPage() - 1);
            } else {
              // reset active
              navigator.setActive(2);
            }
          } else if (index == (navigator.getItemCount() - 2)) {
            if (getPage() < getPageCount() - 1) {
              // nextPage();
              setPage(getPage() + 1);
            } else {
              // reset active
              navigator.setActive(1 + getPageCount());
            }
          } else if (index == (navigator.getItemCount() - 1)) {
            if (getPage() < getPageCount() - 1) {
              lastPage();
            } else {
              // reset active
              navigator.setActive(1 + getPageCount());
            }
          } else {
            setPage(index - 2);
          }
          event.preventDefault();
        }
      }
    }
  }

  /**
   * Creates a indexed pager with the given max visible pagination count.
   */
  public PaginationPager(int visiblePaginations) {
    this.visiblePaginations = visiblePaginations;
    initWidget(navigator);
    navigator.setStyleBase(Navigators.PAGINATION_STYLE);
    this.sinkEvents(Event.ONCLICK);
    setVisible(false);
  }

  @Override
  protected void onRangeOrRowCountChanged() {
    int pageCount = getPageCount();
    int pageIndex = getPage();
    if (pageCount < 2) {
      setVisible(false);
      return;
    }
    // update index
    int startIndex = pageIndex - visiblePaginations / 2;
    if (startIndex < 0) {
      startIndex = 0;
    }
    int endIndex = startIndex + visiblePaginations;
    if (endIndex > pageCount) {
      endIndex = pageCount;
      if (pageCount > visiblePaginations) {
        startIndex = pageCount - visiblePaginations;
      } else {
        startIndex = 0;
      }
    }
    // renew navigations
    navigator.getElement().setInnerText("");
    navigator.addLink(FIRST, "#first");
    navigator.addLink(PREV, "#prev");
    for (int i = startIndex; i < endIndex; i++) {
      navigator.addLink(String.valueOf(i + 1), "#" + String.valueOf(i + 1));
    }
    navigator.addLink(NEXT, "#next");
    navigator.addLink(LAST, "#last");
    navigator.setActive(2 + pageIndex);
    if (pageIndex > 0) {
      navigator.setDisabled(0, false);
      navigator.setDisabled(1, false);
    } else {
      navigator.setDisabled(0, true);
      navigator.setDisabled(1, true);
    }
    if (pageIndex < pageCount - 1) {
      navigator.setDisabled(endIndex + 2, false);
      navigator.setDisabled(endIndex + 3, false);
    } else {
      navigator.setDisabled(endIndex + 2, true);
      navigator.setDisabled(endIndex + 3, true);
    }
    setVisible(true);
  }

}
